/**
 * 
 */
package neptune.manager.validator.rules.topology;

import neptune.manager.model.topology.IPAddress;
import neptune.manager.model.topology.Link;
import neptune.manager.model.topology.NetworkInterface;
import neptune.manager.model.topology.Node;
import neptune.manager.model.topology.Topology;
import neptune.manager.utils.Logger.MessageType;
import neptune.manager.validator.ValidatorResult;
import neptune.manager.validator.ValidatorRule;
import neptune.manager.validator.Validator.Status;

/**
 * @author Roberto Bifulco [RobertoBifulco.it] [info@robertoBifulco.it]
 * 
 */
public class OLPIEndPointIPCoerence extends ValidatorRule<Topology> {

	@Override
	public String getName() {
		return "EndPointIPCoerence";
	}

	@Override
	protected ValidatorResult validationAlgorithm(Topology toValidate,
			ValidatorResult result) {

		for (Link link : toValidate.getLinks()) {
			Node sourceNode = toValidate.searchNodeIntoTopology(link
					.getSource().getNodeId());
			Node destNode = toValidate.searchNodeIntoTopology(link
					.getDestination().getNodeId());

			NetworkInterface sourceIf = sourceNode.getInterfaceByName(link
					.getSource().getInterfaceId());
			NetworkInterface destIf = destNode.getInterfaceByName(link
					.getDestination().getInterfaceId());

			IPAddress sourceIP = null;
			for (IPAddress addr : sourceIf.getIpAddresses()) {
				sourceIP = addr;
			}

			IPAddress destIP = null;
			for (IPAddress addr : destIf.getIpAddresses()) {
				destIP = addr;
			}

			// Questo controllo verifica la coerenza, non la
			// completezza, se non ci sono IP definiti, va oltre.
			if (sourceIP == null || destIP == null)
				continue;

			IPAddress subnet = sourceIP.getSubnetAddress();
			if (!subnet.include(destIP)) {
				result.setStatus(Status.ERROR);
				result
						.getLog()
						.addMessage(
								"Link '"
										+ link.getId()
										+ "' error: the end points aren't on the same subnet. "
										+ "Topology: " + toValidate.getName(),
								MessageType.ERROR);
			}
		}

		return result;
	}

}
